<?php

/**
 * 充值订单模型
 * @property WxPayApi $wxApi
 * @property enum tradeState 订单交易状态(枚举类型): 
 *      PREPAY:预支付,
 *      SUCCESS:支付成功,
 *      REFUND:转入退款,
 *      NOTPAY:未支付,
 *      CLOSED:已关闭,
 *      REVOKED:已撤销（刷卡支付）,
 *      USERPAYING:用户支付中,
 *      PAYERROR:支付失败(其他原因，如银行返回失败)
 */
class Recharge_order_mdl extends MY_Model {
	public $tradeStateCN = array(
			 'SUCCESS'=>'支付成功',
			 'PREPAY'=>'预支付',
			 'NOTPAY'=>'未支付',
			 'USERPAYING'=>'支付中',
			 'REFUND'=>'转入退款',
			 'CLOSED'=>'已关闭',
			 'REVOKED'=>'已撤销',
			 'PAYERROR'=>'支付失败',			
	);
	protected $_table = parent::T_RECHARGE_ORDER;
	/**
	 */
	public function __construct() {
		parent::__construct ();
		$this->load->database();
		$this->load->library('wxApi/WxPayApi',NULL,'wxApi');
	}
	/**
	 * 增加一张充值订单
	 * @param array $data 订单数据,其中:tradeID字段如果与已有重复,会插入失败
	 */
	public function addPrepayOrder($data){
	    $sql = $this->db->insert_string($this->_table,$data);
	    $sql = str_replace('INSERT ', 'INSERT IGNORE ', $sql);
	    if( $this->db->query($sql) ){
	        $id = $this->db->insert_id();
	        return empty($id) ? FALSE : $id;
	    }
	    return FALSE;
	}
	/**
	 * 需要到微信系统查询的状态(预支付,支付中)
	 * @var array
	 */
	public  $needQueryState = array ('PREPAY','USERPAYING','NOTPAY');
	/**
	 * 获取订单最新状态
	 * @abstract 如果订单状态为"预支付","支付中","未支付",会向微信API请求最新结果并更新
	 * @param array|int	订单详情数组或订单ID
	 * @param bool 当交易状态变为成功后是否需要更新用户余额(默认TRUE)
	 * @return array 返回支付订单表的所有字段及以下字段:
	 * 		<p>--tradeStateChanged 	: boolean	交易状态是否发生改变
	 * 		<p>--tradeStateDesc	 	: string	交易状态详情(中文)
	 */
	public function queryOrderResult($order,$updateUserBalance=TRUE){
		// ==== 检查订单 ====
		if ( is_numeric($order) OR ! isset($order['tradeState']) OR ! isset($order['tradeID']) OR !isset($order['userID']) ) {
	    	$order = $this->getOneById($order);
	    }
	    if( empty($order) ){
	    	return FALSE;
	    }
	    
		$order['tradeStateChanged'] = FALSE;// 订单交易状态是否改变的标识
		$order['tradeStateDesc'] = ''; //交易状态详情(中文)
		
		// 判断订单状态:已经有结果则直接返回 
		if ( ! empty ( $order ['tradeState'] ) && ! in_array ( $order ['tradeState'], $this->needQueryState )){
			$order['tradeStateDesc'] = $this->getTradeStateDesc($order['tradeState']);
			return $order;
		}
		// ==== END 检查订单 ====
		
		// ==== 调用微信API查询订单 =========
		try {
			$result = $this->wxApi->orderQuery ( $order ['tradeID'] );
			if( empty($result) ){
				$log = array();
				$log['orderID'] = $order['id'];
				$log['msg'] = '微信接口错误';
				$log['queryResult'] = $result;
				$log['error']  = $this->wxApi->getErrors();
				$this->queryLog($log);
				return FALSE;
			}
			// 如果查询到的结果有变化,更新到订单表
			$update = array ();
			if ($result ['trade_state'] != $order ['tradeState']) {
				$order['tradeStateChanged'] = TRUE;//标识订单状态为已改变
				$update ['tradeState'] = $result ['trade_state'];
			}
			if (! empty ( $result ['transaction_id'] ) && $result ['transaction_id'] != $order ['wxTransactionID']) {
				$update ['wxTransactionID'] = $result ['transaction_id'];
			}
			if (! empty ( $update )) {
				$where = array('id'=>$order['id']);
				if ( ! $this->update($where, $update)) {
					throw new Exception('数据库错误:更新失败');
				}
			}
			$order ['tradeState'] = $result ['trade_state'];
			if( !empty($result['trade_state_desc']) ){
				$order['tradeStateDesc'] = $result['trade_state_desc'];
			}else{
				$order['tradeStateDesc'] = $this->getTradeStateDesc($order['tradeState']);
			}
// 			// 如果不需要更新用户余额,返回结果
// 			if( ! $updateUserBalance ){
// 				return $order;
// 			}
			// 如果交易状态为成功,更新用户余额
// 			if( $result['trade_state'] == 'SUCCESS' ){
				
				
// 				$res = $this->db->set('balance','balance + '.$result ['total_fee'],FALSE)
// 								->where('id',$order['userID'])
// 								->update(parent::T_USER);
// 				if( ! $res ){
// 					throw new Exception('数据库错误:更新用户余额失败');
// 				}
// 			}
			return $order;
				
		} catch (Exception $e) {
				$log = array();
				$log['orderID'] = $order['id'];
				$log['msg'] = $e->getMessage();
				$log['queryResult'] = $result;
				$log['error']  = $e->getTraceAsString();
				$this->queryLog($log);
				return FALSE;
		}
	}
	
	public function getTradeStateDesc($state){
		return isset($this->tradeStateCN[$state]) ? $this->tradeStateCN[$state] : '状态异常';
	}
	
	public function queryLog($data){
		$data['time']  = date('Y-m-d H:i:s');
		$data['debug'] = MyDebug::$data;
		
		$file = APPPATH.'logs/rechargeLog/'.date('Y_m_d_h');
		$data = json_encode($data,JSON_UNESCAPED_UNICODE)."\n";
		return file_put_contents($file, $data,FILE_APPEND);
	}
}

